TypeScriptはJavaScriptに型システムを追加した言語で、2026年現在、フロントエンド・バックエンド問わず、もはやデファクトスタンダードとなっています。本記事では、JavaScript経験者がスムーズにTypeScriptに移行するための完全ガイドを提供します。

💡 この記事のポイント

TypeScriptは「型のあるJavaScript」です。既存のJavaScriptコードはそのままTypeScriptとして動作するため、段階的に導入できます。

1. なぜTypeScriptを学ぶべきか

  • バグの早期発見:コンパイル時に型エラーを検出(実行前に約15%のバグを防止)
  • 優れたDX:IDEの補完機能・リファクタリングが大幅に向上
  • ドキュメント代わり:型定義がコードの仕様書になる
  • 業界標準:npm上位パッケージの90%以上がTS対応

2. 基本の型

// プリミティブ型
let name: string = "TechPulse";
let age: number = 3;
let isActive: boolean = true;

// 配列
let tags: string[] = ["AI", "Web", "Cloud"];
let numbers: Array<number> = [1, 2, 3];

// オブジェクト型
let article: {
  title: string;
  views: number;
  published: boolean;
} = {
  title: "TypeScript入門",
  views: 1500,
  published: true
};

// Union型(複数の型を許容)
let id: string | number = "abc123";
id = 42; // これもOK

// リテラル型
type Category = "AI" | "Web" | "Cloud" | "DevOps";
let category: Category = "AI"; // この4つ以外はエラー

// Optional型
function greet(name: string, greeting?: string): string {
  return `${greeting ?? "こんにちは"}, ${name}さん!`;
}
広告

3. インターフェースと型エイリアス

// インターフェース(拡張可能)
interface User {
  id: number;
  name: string;
  email: string;
  role: "admin" | "editor" | "viewer";
}

interface Admin extends User {
  role: "admin";
  permissions: string[];
}

// 型エイリアス(Union型に便利)
type ApiResponse<T> =
  | { status: "success"; data: T }
  | { status: "error"; message: string };

// 使用例
function fetchUser(id: number): ApiResponse<User> {
  // ...
  return { status: "success", data: user };
}

const result = fetchUser(1);
if (result.status === "success") {
  console.log(result.data.name); // 型安全!
  // result.messageにはアクセスできない(コンパイルエラー)
}

4. ジェネリクス

ジェネリクスは型の再利用性を高める仕組みです。

// ジェネリック関数
function getFirst<T>(items: T[]): T | undefined {
  return items[0];
}

const firstNumber = getFirst([1, 2, 3]);      // number | undefined
const firstString = getFirst(["a", "b", "c"]); // string | undefined

// ジェネリック型制約
interface HasId {
  id: number;
}

function findById<T extends HasId>(items: T[], id: number): T | undefined {
  return items.find(item => item.id === id);
}

// ジェネリッククラス
class Repository<T extends HasId> {
  private items: T[] = [];

  add(item: T): void {
    this.items.push(item);
  }

  findById(id: number): T | undefined {
    return this.items.find(item => item.id === id);
  }

  getAll(): T[] {
    return [...this.items];
  }
}

5. ユーティリティ型

TypeScriptには便利な組み込みユーティリティ型が豊富にあります。

interface Article {
  id: number;
  title: string;
  content: string;
  author: string;
  publishedAt: Date;
}

// Partial - すべてのプロパティをオプショナルに
type ArticleUpdate = Partial<Article>;

// Pick - 特定のプロパティだけ抽出
type ArticleSummary = Pick<Article, "id" | "title" | "author">;

// Omit - 特定のプロパティを除外
type NewArticle = Omit<Article, "id">;

// Record - キーと値の型を指定
type CategoryCount = Record<Category, number>;

// Readonly - すべてのプロパティを読み取り専用に
type ImmutableArticle = Readonly<Article>;

6. JSからTSへの移行戦略

  1. tsconfig.jsonの作成strict: falseで始め、段階的に厳格化
  2. ファイル名変更.js.tsを1ファイルずつ
  3. any型の許容:最初はanyで通し、後から型を付ける
  4. strictモード有効化:チームの理解が進んだらstrict: true
// tsconfig.json(段階的移行向け)
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "strict": false,          // 最初はfalse
    "allowJs": true,          // JSファイルも許容
    "checkJs": false,         // JSの型チェックはoff
    "outDir": "./dist",
    "esModuleInterop": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*"]
}

TypeScriptは一度学べば生産性が飛躍的に向上する技術です。まずは小さなプロジェクトから導入し、型の恩恵を実感してみてください。